#include <stc15f2k60s2.h>
#include <string.h>

#include "Uart2.h"
#include "Timer0.h"
#include "Delay.h"
#include "Types.h"
#include "SIMCOM4G.h"

#define AT_CMD_PREFIX 		"AT"
#define AT_CMD_CONCAT      	"+"
#define AT_CMD_JOIN_PARAMS 	"="
#define AT_CMD_SUFFIX 	    "\r\n"

/* FTP服务相关命令 */
#define AT_CMD_TEST        AT_CMD_PREFIX AT_CMD_SUFFIX
#define AT_CMD_FTP_START   AT_CMD_PREFIX AT_CMD_CONCAT"CFTPSSTART" AT_CMD_SUFFIX
#define AT_CMD_FTP_STOP    AT_CMD_PREFIX AT_CMD_CONCAT"CFTPSSTOP" AT_CMD_SUFFIX
#define AT_CMD_FTP_LOGIN   AT_CMD_PREFIX AT_CMD_CONCAT"CFTPSLOGIN"
#define AT_CMD_FTP_LIST    AT_CMD_PREFIX AT_CMD_CONCAT"CFTPSLIST" AT_CMD_JOIN_PARAMS
#define AT_CMD_FTP_GET     AT_CMD_PREFIX AT_CMD_CONCAT"CFTPSGET" AT_CMD_JOIN_PARAMS
#define AT_CMD_FTP_LOGOUT  AT_CMD_PREFIX AT_CMD_CONCAT"CFTPSLOGOUT" AT_CMD_SUFFIX

/* FTP服务器参数 */
#define FTP_SERVER_IP    "120.25.168.77"
#define FTP_PORT         "21"
#define FTP_USERNAME     "car"
#define FTP_PASSWORD     "123456"

/* 组合命令宏 */
#define BUILD_FTP_LOGIN_CMD() \
    AT_CMD_FTP_LOGIN "\"" FTP_SERVER_IP "\"," FTP_PORT ",\"" FTP_USERNAME "\",\"" FTP_PASSWORD "\",0" AT_CMD_SUFFIX

#define BUILD_FTP_LIST_CMD(path) \
    AT_CMD_FTP_LIST "\"" path "\"" AT_CMD_SUFFIX

#define BUILD_FTP_GET_CMD(filepath) \
    AT_CMD_FTP_GET "\"" filepath "\"" AT_CMD_SUFFIX


#define AT_CMD_SIZE 128 // 最大指令长度
#define PARAM_BUFFER_SIZE 64 // 参数缓冲区大小
#define RESPONSE_BUFFER_SIZE 32 // 响应缓冲区大小
#define RESPONSE_DATA_SIZE 256 // 接收数据大小

static xdata char at_cmd_buffer[AT_CMD_SIZE] = {0}; // 静态缓冲区，注意多线程问题
static xdata char at_cmd_param[PARAM_BUFFER_SIZE] = {0}; // 指令参数
static xdata char at_cmd_response[RESPONSE_BUFFER_SIZE] = {0}; // 指令响应

static xdata char response_data[RESPONSE_DATA_SIZE] = {0}; // 接收指令数据

static xdata char at_replyCmd_buffer[32] = {0};

uint8_t at_cmd_start_flag = 0; // 指令开始标志
uint16_t at_cmd_timeout = 0; // 状态时间戳
unsigned char at_cmd_response_flag = 0; // 响应标志位

uint8_t retry_count = 0; // 指令超时重试次数

uint8_t FTP_Server_Start_Flag = 0; // FTP服务启动标志位

// 函数声明
char* build_at_command(const char* cmd, const char* param);
//char* build_multi_param_command(const char* command, ...); // 多参数命令扩展


// 指令信息结构体
typedef struct {
	char command[16]; // 命令名称
	char params[64]; // 参数
    char response[16]; // 响应
    uint16_t timeout; // 超时时间
    uint8_t state; // 指令状态
} AT_Command_Info;


// 多参数命令封装结构体
typedef struct {
    const char* command;  // 命令名称（如"CFTPSSTART"）
    const char* params; 	// 参数 （如"120.25.168.77,21,car,123456,0"）
} AT_Command_Param;


// rx_buffer中需求读取的数据位置信息
typedef struct {
    char* buffer; // 接收缓冲区
    uint16_t len; // 数据长度
}Read_Rx_Buf_info;


// AT指令状态
typedef enum {
    AT_IDLE,                // 空闲状态
    AT_START,               // 开始处理指令
    AT_SENDING,             // 发送AT指令
    WAITING_RESPONSE,       // 等待模块响应
    AT_SUCCESS,             // 操作成功
	AT_ERROR,				// 操作错误
    AT_TIMEOUT              // 操作超时
} AT_Command_State;
AT_Command_State current_state = AT_IDLE;   // 当前状态


// AT指令错误状态
typedef enum {
    AT_ERR_NONE,            // 无错误
    AT_ERR_NO_RESPONSE,     // 无响应
    AT_ERR_INVALID_CMD,     // 无效命令
    AT_ERR_INVALID_PARAM,   // 无效参数
    AT_ERR_TIMEOUT,         // 超时
    AT_ERR_BUSY             // 忙
} AT_Command_Error;
AT_Command_Error error_code = AT_ERR_NONE; // 错误代码


// 错误处理操作状态
typedef enum {
    AT_ERR_OP_IDLE,             // 空闲状态
    AT_ERR_OP_AT_TEST,          // AT指令测试
    AT_ERR_OP_QUERY_RSSI,       // 查询信号强度
    AT_ERR_OP_CHECK_NETWORK,    // 网络连接检查
    AT_ERR_OP_ABORT,            // 终止
    AT_ERR_OP_REBOOT            // 重启

} SIMCOM_Error_Op_State;
SIMCOM_Error_Op_State error_op_state = AT_ERR_OP_IDLE; // 错误处理操作状态


// FTP服务状态
typedef enum {
    FTP_IDLE,               // 空闲状态
    FTP_START,              // 开启服务状态
    FTP_LOGIN,              // 登录状态
    FTP_RUNNING,            // 运行状态
    FTP_LOGOUT,             // 登出状态
    FTP_STOP                // 关闭服务状态
} FTP_Server_State;
FTP_Server_State ftp_state = FTP_IDLE; // 当前FTP状态


// FTP操作状态
typedef enum {
    FTP_OP_IDLE,           // 空闲状态
    FTP_OP_LIST,           // 列出目录状态
    FTP_OP_GET             // 下载文件状态
} FTP_Op_State;
FTP_Op_State ftp_op_state = FTP_OP_IDLE; // 当前FTP操作状态


// FTP指令响应数据处理类型
typedef enum {
    FTP_CMD_RESP_DATA_NONE, // 无数据
    FTP_CMD_RESP_DATA_ONE,	// 单个
    FTP_CMD_RESP_DATA_FILE_LIST, // 文件列表数据
    FTP_CMD_RESP_DATA_FILE_DATA // 文件数据
} FTP_CMD_Response_Data_Type;


// 4G模块初始化
void SIMCOM4G_Init(void)		
{
//	Uart1_Init();
//	Uart2_Init();// 串口2初始化
	UART2_Send_String("AT\r\n");// 测试AT
	Delayms(1000);
	
	UART2_Send_String("AT+CFTPSSTART\r\n");// 开启FTP服务
	Delayms(3000);
	
	UART2_Send_String("AT+CFTPSLOGIN=\"120.25.168.77\",21,\"car\",\"123456\",0\r\n");// 登录FTP服务器
	Delayms(8000);
	
	UART2_Send_String("AT+CFTPSLIST=\"./\"\r\n");// 查看当前路径下的文件
	Delayms(5000);
	
	UART2_Send_String("AT+CFTPSGET=\"/car/car.bin\"\r\n");// 获取"/car/car.bin"文件
	Delayms(6000);
	
	UART2_Send_String("AT+CFTPSLOGOUT\r\n");// 登出FTP连接
	Delayms(3000);
	
	UART2_Send_String("AT+CFTPSSTOP\r\n");// 关闭FTP服务
	Delayms(3000);
}


/*
* 
* @param: 无
* @return: 无
*/
void FTP_Server_Applictaion(void) 
{
    FTP_Server_Start_Flag = 1; // 开启FTP服务标志位
}


/*
* @param cmd: AT指令名称
* @param param: AT指令参数
* @param response: 期望的响应字符串
* @param timeout: 超时时间
* @return: 无
*/
void AT_Command_Applictaion(const char* cmd, const char* param, const char* response, uint16_t timeout) {

    /* 格式化缓冲区 */
    memset(at_cmd_buffer, 0, sizeof(at_cmd_buffer)); // 格式化指令缓冲区
    memset(at_cmd_param, 0, sizeof(at_cmd_param)); // 格式化参数缓冲区
    memset(at_cmd_response, 0, sizeof(at_cmd_response)); // 格式化响应缓冲区
	
    /* 组装AT指令 */
	// 追加命令
	strcat(at_cmd_response, response);
		
		
    // 构造AT指令
    if((cmd[0] == 'A' && cmd[1] == 'T'))
    {
		strcat(at_cmd_buffer, "+");
    } else {
        strcat(at_cmd_buffer, "AT+");
    }
    
    strcat(at_cmd_buffer, cmd); // 追加指令名称
    if(param != NULL) {
        strcat(at_cmd_buffer, "="); // 追加参数分隔符
        strcat(at_cmd_buffer, param); // 追加参数
    } 
	strcat(at_cmd_buffer, "\r\n"); // 追加回车换行符


    /* 配置标志位 */

    at_cmd_response_flag = 0; // 响应标志位

    at_cmd_timeout = timeout; // 超时时间

    at_cmd_start_flag = 1;  // 指令开始标志
	
	
	/* 判断指令类别 */
	AT_Command_Response_Applictaion(cmd);
	
}


/*
* @param cmd: AT指令名称
* @param cmd_type: AT指令类型
* @return: 无
*/
void AT_Command_Response_Applictaion(const char* cmd)
{
    // at_cmd_response_flag = 1; // 响应标志位
	memset(at_replyCmd_buffer, 0, sizeof(at_replyCmd_buffer));
	strcat(at_replyCmd_buffer, "+");
	strcat(at_replyCmd_buffer, cmd);
	strcat(at_replyCmd_buffer, ": 0");
}

void Get_Response_Data_Handler() {
    
    static enum{S0, S1, S2, S3}Response_Data_State = S0;
	static uint16_t timestamp = 0;

    switch (Response_Data_State)
    {
        case S0:
        {
            // 空闲
            if(at_cmd_response_flag != 0) {
                // UART2_Send_String("AT Success!\r\n");
				retry_count = 0; // 重试次数清零
                Response_Data_State = S1; // 进入下一状态
            }
        } break;
        case S1:
            {
				
			static enum {S0, S1} State = S0;
				static const uint16_t delay_time = 1000;
				
				switch(State) {
					case S0:
						timestamp = GetSystemTick(); // 获取系统时间戳
						State = S1;
						break;
					case S1:
						if((GetSystemTick() - timestamp) >= delay_time) {
							// UART2_Send_String("AT Get_Response_Data_Handler - 1\r\n");
//							UART2_Send_String(at_replyCmd_buffer);
							// 当前的指令状态
							if(strstr(uart2_rx_buffer, "OK") != NULL) {
								// UART2_Send_String("find OK\r\n");
								Response_Data_State = S2;
								State = S0;
							} else {
                                UART2_Send_String("not find OK\r\n");
                            }
							timestamp = GetSystemTick(); // 获取系统时间戳
						}
						break;
					default: {State = S0;} break;
				} 
            } break;
        case S2:
            {
                // 开始处理数据
				
				Response_Data_State = S3;
            } break;
        case S3:
            {
                // 处理完毕
                at_cmd_start_flag = 0; // 指令开始标志
				current_state = AT_IDLE;
				Response_Data_State = S0;
            } break;
        default:{Response_Data_State = S0;} break;
    }

}

char *last_strstr(char* s, char* t)
{
    char *last = NULL;
    char *tmp = (char *)s;
    while ((tmp = strstr(tmp, t)) != NULL) {
        last = tmp;    // 更新最后一次匹配位置
        tmp++;         // 跳过当前匹配位置，继续向后搜索
    }
    return last;
}

void Get_Response_Data(char* dat, uint16_t len) {
    memcpy(dat, response_data, len); // 复制数据到指定缓冲区
}

// FTP服务指令处理器
void FTP_Server_Process_Handler() {
	static enum{SendCmd, WaitReply} CmdStatus = SendCmd;

    switch(ftp_state) {
        case FTP_IDLE:
        {
			switch(CmdStatus) 
			{
				case SendCmd: {
					// 空闲状态处理
					// 1. 发送开启指令
					// 2. 配置
					// if(at_cmd_start_flag != 0)
					{
						AT_Command_Applictaion("CFTPSSTART", NULL, "OK", 9000);
						CmdStatus = WaitReply;
					}
				} break;
				case WaitReply: {
					if(at_cmd_start_flag == 0) {
						ftp_state = FTP_START; // 切换到开启服务状态
						CmdStatus = SendCmd;
					}
				} break;
				default: { CmdStatus = SendCmd; } break;
			}
        }break;
        case FTP_START:
        {
            // 登录处理
			switch(CmdStatus) 
			{
				case SendCmd: {
					// 空闲状态处理
					// 1. 发送开启指令
					// 2. 配置
					// if(at_cmd_start_flag != 0)
					{
						AT_Command_Applictaion("CFTPSLOGIN","\"120.25.168.77\",21,\"car\",\"123456\",0", "OK", 9000);
						CmdStatus = WaitReply;
					}
				} break;
				case WaitReply: {
					if(at_cmd_start_flag == 0) {
						ftp_state = FTP_LOGIN; // 切换到登录状态
						CmdStatus = SendCmd;
					}
				} break;
				default: { CmdStatus = SendCmd; } break;
			}
        }break;
        case FTP_LOGIN:
        {
            // 运行状态处理
			switch(CmdStatus) 
			{
				case SendCmd: {
					// 空闲状态处理
					// 1. 发送开启指令
					// 2. 配置
					// if(at_cmd_start_flag != 0)
					{
						AT_Command_Applictaion("CFTPSPWD", NULL, "OK", 9000);
						CmdStatus = WaitReply;
					}
				} break;
				case WaitReply: {
					if(at_cmd_start_flag == 0) {
						ftp_state = FTP_RUNNING; // 切换到登录状态
						CmdStatus = SendCmd;
					}
				} break;
				default: { CmdStatus = SendCmd; } break;
			}

        }break;
        case FTP_RUNNING:
        {
            // 运行状态处理
        }break;
        case FTP_LOGOUT:
        {
            // 登出处理
        }break;
        case FTP_STOP:
        {
            // 关闭服务处理

            FTP_Server_Start_Flag = 0; // 关闭FTP服务标志位
            ftp_state = FTP_IDLE; // 切换到空闲状态
        }break;
        default: {ftp_state = FTP_IDLE;} break;
    }

}


// AT指令错误处理
void HandleATError(void) {
//    static uint16_t ErrorTimestamp = 0;
//	
//    if((GetSystemTick() - ErrorTimestamp) >= 500 && !ErrorTimestamp) {
//        UART2_Send_String("AT+CSQ\r\n"); // 查询信号强度
//		ErrorTimestamp = GetSystemTick(); // 状态时间戳
//    }
	
	UART2_Send_String("AT+CSQ\r\n"); // 查询信号强度
}

// 错误处理器
void HandleFatalError(void) {
    
    // AT指令错误处理
    HandleATError();

    // FTP服务错误处理

    // SIMCOM模块错误处理

}



// 非阻塞AT指令处理器
void AT_ProcessHandler() {
//    static uint8_t retry_count = 0; // 指令超时重试次数
	static uint16_t timestamp = 0;
    
    switch(current_state) {
        case AT_IDLE: {
            // AT指令开始处理
            if(at_cmd_start_flag != 0) {
                // 初始化新命令
                memset(uart2_rx_buffer, 0, sizeof(uart2_rx_buffer)); // 格式化接收缓冲区
                rx_index = 0;	// 重置下标
								
                current_state = AT_START; // 切换到测试状态
            }
        } break;
        case AT_START: {
            // 测试AT
			UART2_Send_String(at_cmd_buffer);

            // 更新状态 发送
            current_state = AT_SENDING;
			// 获取系统时间戳
            timestamp = GetSystemTick(); 
        } break;
        case AT_SENDING: { 
            // 等待数据发送完成（实际需根据硬件标志判断）
            if(Uart2_Send_Byte_Flag || (GetSystemTick() - timestamp) >= 500) {
				// 发送成功，更新状态 等待回应
                current_state = WAITING_RESPONSE;
                timestamp = GetSystemTick();// 获取系统时间戳
            }
        } break;
        case WAITING_RESPONSE: { 
			if((GetSystemTick() - timestamp) >= at_cmd_timeout) 
			{
				// 检查是否收到OK
				if(strstr(uart2_rx_buffer, "OK") != NULL) { // "AT\r\r\nOK\r\n"
					// 更新状态 指令完成
					// AT_Command_Response_Applictaion(at_cmd_buffer);
					at_cmd_response_flag = 1;
					current_state = AT_SUCCESS;
				} else if(strstr(uart2_rx_buffer, "ERROR") != NULL) {
					
					current_state = AT_ERROR;	// 更新状态 错误
				}
				// 超时处理
				else {
					current_state = AT_TIMEOUT; // 更新状态 重试
				}
			}
        } break;   
        case AT_SUCCESS: { 
            // 成功处理逻辑
			
			// 处理数据
            Get_Response_Data_Handler();
            

            // 这里可以触发下一个AT指令
            // current_state = AT_IDLE;
        } break;
        case AT_ERROR: {
            
            // retry_count = 0; // 重试次数清零

            // current_state = AT_TIMEOUT; // 超时状态
			
			
			static enum {S0, S1} State = S0;
                    static const uint16_t delay_time = 1000;
                    
                    switch(State) {
                        case S0:
                            timestamp = GetSystemTick(); // 获取系统时间戳
                            State = S1;
                            break;
                        case S1:
                            if((GetSystemTick() - timestamp) >= delay_time) {
                                UART2_Send_String("AT+CBC\r\n"); // 查询信号强度
								at_cmd_start_flag = 0; // 指令开始标志

                                timestamp = GetSystemTick(); // 获取系统时间戳
                            }
                            break;
                        default: {State = S0;} break;
                    } 
			
            } break;
        case AT_TIMEOUT: {
                // 超时重试逻辑
                if(retry_count < 3) {
                    current_state = AT_IDLE;
                    retry_count++; // 重试次数加1
                } else {
                    // 超过重试次数的错误处理
                    ///////// HandleFatalError(); ///////// 
                                
                    static enum {S0, S1} State = S0;
                    static const uint16_t delay_time = 1000;
                    
                    switch(State) {
                        case S0:
                            timestamp = GetSystemTick(); // 获取系统时间戳
                            State = S1;
                            break;
                        case S1:
                            if((GetSystemTick() - timestamp) >= delay_time) {
                                HandleFatalError(); // 触发错误处理
                                
                                timestamp = GetSystemTick(); // 获取系统时间戳
                            }
                            break;
                        default: {State = S0;} break;
                    } 
                }
            } break;
		default: {current_state = AT_IDLE;} break;
    }
}


